/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 * Description: verbs接口封装
 * Author: lilianlin
 * Create: 2022-02-18
 */

#include "adapter_verbs.h"
#include <functional>

#include "log.h"
#include "dlibv_function.h"

namespace hccl {
HcclResult hrtIbvPostSrqRecv(struct ibv_srq *srq, struct ibv_recv_wr *wr, struct ibv_recv_wr **badWr)
{
    s32 ret = ibv_post_srq_recv(srq, wr, badWr);
    CHK_PRT_RET(ret != 0, HCCL_ERROR("ibv_post_srq_recv failed. errno:%d ret: %d", errno, ret), HCCL_E_NETWORK);
    return HCCL_SUCCESS;
}

HcclResult hrtIbvPostRecv(struct ibv_qp *qp, struct ibv_recv_wr *wr, struct ibv_recv_wr **badWr)
{
    s32 ret = ibv_post_recv(qp, wr, badWr);
    CHK_PRT_RET(ret == ENOMEM, HCCL_WARNING("post recv wqe overflow.[%d]", ret), HCCL_E_AGAIN);
    CHK_PRT_RET(ret != 0, HCCL_ERROR("ibv_post_recv failed. errno:%d ret: %d", errno, ret), HCCL_E_NETWORK);
    return HCCL_SUCCESS;
}

HcclResult hrtIbvPostSend(struct ibv_qp *qp, struct ibv_send_wr *wr, struct ibv_send_wr **badWr)
{
    s32 ret = ibv_post_send(qp, wr, badWr);
    CHK_PRT_RET(ret == ENOMEM, HCCL_WARNING("post send wqe overflow.[%d]", ret), HCCL_E_AGAIN);
    CHK_PRT_RET(ret != 0, HCCL_ERROR("ibv_post_send failed. errno:%d", ret), HCCL_E_NETWORK);
    return HCCL_SUCCESS;
}

HcclResult hrtIbvPollCq(struct ibv_cq *cq, int maxNum, struct ibv_wc *wc, s32& num)
{
    int pollNum = 0;
    pollNum = ibv_poll_cq(cq, maxNum, wc);
    num = pollNum;
    CHK_PRT_RET((num < 0), HCCL_ERROR("ibv_poll_cq failed. num:%d", num), HCCL_E_NETWORK);
    return HCCL_SUCCESS;
}

HcclResult hrtIbvReqNotifyCq(struct ibv_cq *cq, int solicitedOnly)
{
    s32 ret = ibv_req_notify_cq(cq, solicitedOnly);
    CHK_PRT_RET(ret != 0, HCCL_ERROR("ibv_req_notify_cq failed. errno:%d", ret), HCCL_E_NETWORK);
    return HCCL_SUCCESS;
}

HcclResult hrtIbvGetCqEvent(struct ibv_comp_channel *channel, struct ibv_cq **cq, void **cq_context)
{
    s32 ret = DlIbvFunction::GetInstance().dlRcoeGetCqEvent(channel, cq, cq_context);
    CHK_PRT_RET(ret != 0, HCCL_ERROR("hrtIbvGetCqEvent failed. errno:%d", ret), HCCL_E_NETWORK);
    return HCCL_SUCCESS;
}

void hrtIbvAckCqEvent(struct ibv_cq *qp, unsigned int nevents)
{
    DlIbvFunction::GetInstance().dlRcoeAckCqEvent(qp, nevents);
    return;
}

HcclResult hrtIbvQueryQp(struct ibv_qp *qp)
{
    struct ibv_qp_attr attr{};
    struct ibv_qp_init_attr init_attr{};
    CHK_RET(DlIbvFunction::GetInstance().DlIbvFunctionInit());
    s32 ret = DlIbvFunction::GetInstance().dlRcoeQueryQp(qp, &attr, IBV_QP_STATE, &init_attr);
    CHK_PRT_RET(ret != 0, HCCL_ERROR("hrtIbvQueryQp failed. errno:%d", ret), HCCL_E_NETWORK);
    return HCCL_SUCCESS;
}

}
